package com.letoken.platform.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.letoken.platform.app.consumer.FundConsumer;
import com.letoken.platform.app.consumer.FundReleaseConsumer;
import com.letoken.platform.app.service.AppFundInfoService;
import com.letoken.platform.app.service.AppFundV2InfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.letoken.platform.app.service.AppUserLampService;
import com.letoken.platform.app.service.AppUserWalletService;
import com.letoken.platform.pub.enums.LetokenTokenTypeEnum;
import com.letoken.platform.pub.enums.TokenTransactionStatusEnum;
import com.letoken.platform.pub.enums.TokenTransactionTypeEnum;
import com.letoken.platform.repo.app.dao.*;
import com.letoken.platform.repo.app.po.*;
import com.letoken.platform.repo.app.req.user.QueueWeightingReq;
import com.letoken.platform.repo.helper.CalculateConsumerValue;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 作者
 * @since 2024-02-18
 */
@Service
@Slf4j
public class AppFundV2InfoServiceImpl extends ServiceImpl<AppFundV2InfoMapper, AppFundV2Info> implements AppFundV2InfoService {
    @Resource
    AdminFundV2ConfigMapper adminFundV2ConfigMapper;

    @Autowired
    AppFundV2InfoMapper appFundV2InfoMapper;

    @Autowired
    AppUserWalletMapper appUserWalletMapper;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    AppUserLampService appUserLampService;

    @Autowired
    private AppFundInfoService appFundInfoService;

    @Autowired
    AppUserWalletService appUserWalletService;
    @Resource
    AppFundInfoMapper appFundInfoMapper;

    @Resource
    AdminFundLevelConfigMapper adminFundLevelConfigMapper;

    @Autowired
    CalculateConsumerValue calculateConsumerValue;


    @Override
    public void income() {
        AdminFundV2Config adminFundV2Config = adminFundV2ConfigMapper.getMinNumber();
        List<AdminFundV2Config> configList = adminFundV2ConfigMapper.getFundV2ConfigList();
        List<AppFundV2Info> infoList = appFundV2InfoMapper.getFundV2List(adminFundV2Config.getMinNumber());
        BigDecimal bigDecimal = BigDecimal.ZERO;
        for (AppFundV2Info appFundV2Info : infoList) {
            for (AdminFundV2Config fundV2Config : configList) {
                try {
                    if (appFundV2Info.getRetained().compareTo(fundV2Config.getMinNumber()) >= 0) {
                        appFundV2Info = appFundV2InfoMapper.selectBYUserId(appFundV2Info.getUserId());
                        if (ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(BigDecimal.ZERO) == 0)
                            continue;
                        BigDecimal reward = appFundV2Info.getRetained().divide(new BigDecimal("2")).multiply(fundV2Config.getRate());

                        if (reward.compareTo(appFundV2Info.getRetained()) > 0) {
                            reward = appFundV2Info.getRetained();
                        }
                        bigDecimal = bigDecimal.add(reward);
                        AppFundV2Info appFundV2Info1 = appFundInfoService.updateInfo(appFundV2Info.getUserId(), reward, BigDecimal.ZERO);
                        AppFundV2Detail appFundV2Detail = new AppFundV2Detail();
                        appFundV2Detail.setAmount(reward);
                        appFundV2Detail.setUserId(appFundV2Info.getUserId());
                        appFundV2Detail.setCreateTime(LocalDateTime.now());
                        appFundV2Detail.setAfterAmount(appFundV2Info1.getRetained());
                        appFundV2Detail.setType(2);
                        appFundV2Detail.insert();

                        appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(), appFundV2Info.getUserId(), reward, TokenTransactionTypeEnum.FUND_REWARD.getValue(), "");

                        //给上级带来奖励的总额
                        queueBonus(appFundV2Info.getUserId(), reward, appFundV2Info.getUserId());
                        // appUserLampService.updateLamd(appFundV2Info.getUserId(),reward.divide(new BigDecimal(5)).negate());
                        fundRelease(appFundV2Info.getUserId(), reward);
                        break;
                    }
                } catch (Exception e) {
                    log.info("执行基金发型收益用户id:"+appFundV2Info.getUserId()+"错误日志:"+e);
                }
            }
        }
        weighting(bigDecimal);
        incomeGive(adminFundV2Config, configList);
    }

    public void fundRelease(Integer userId, BigDecimal amount) {
        FundReleaseConsumer.FundReleaseDto dto = new FundReleaseConsumer.FundReleaseDto();
        dto.setAmount(amount.negate());
        dto.setUserId(userId);
        rabbitTemplate.convertAndSend(FundReleaseConsumer.queue, JSONObject.toJSON(dto).toString());
    }

    public void queueBonus(Integer userId, BigDecimal amount, Integer sourceUserId) {
        FundConsumer.BonusDto dto = new FundConsumer.BonusDto();
        dto.setAmount(amount);
        dto.setUserId(userId);
        dto.setSourceUserId(sourceUserId);
        rabbitTemplate.convertAndSend(FundConsumer.exchange, FundConsumer.queueBonus, JSONObject.toJSON(dto).toString());
    }

    public void queueWeighting(BigDecimal amount) {
        rabbitTemplate.convertAndSend(FundConsumer.exchange, FundConsumer.queueWeighting, amount);
    }


    public void incomeGive(AdminFundV2Config adminFundV2Config, List<AdminFundV2Config> configList) {
        List<AppFundV2Info> infoList = appFundV2InfoMapper.getFundV2GiveList(adminFundV2Config.getMinNumber());
        for (AppFundV2Info appFundV2Info : infoList) {
            try {
                for (AdminFundV2Config fundV2Config : configList) {
                    if (appFundV2Info.getGive().compareTo(fundV2Config.getMinNumber()) >= 0) {
                        appFundV2Info = appFundV2InfoMapper.selectBYUserId(appFundV2Info.getUserId());
                        if (ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getGive().compareTo(BigDecimal.ZERO) == 0)
                            continue;

                        BigDecimal giveReward = BigDecimal.ZERO;
                        if (appFundV2Info.getGive().compareTo(BigDecimal.ZERO) > 0) {
                            giveReward = appFundV2Info.getGive().multiply(fundV2Config.getRate());
                        }

                        AppFundV2Info appFundV2Info1 = appFundInfoService.updateInfo(appFundV2Info.getUserId(), BigDecimal.ZERO, giveReward);
                        AppFundV2Detail appFundV2Detail2 = new AppFundV2Detail();
                        appFundV2Detail2.setAmount(giveReward);
                        appFundV2Detail2.setUserId(appFundV2Info.getUserId());
                        appFundV2Detail2.setCreateTime(LocalDateTime.now());
                        appFundV2Detail2.setAfterAmount(appFundV2Info1.getGive());
                        appFundV2Detail2.setType(10);
                        appFundV2Detail2.insert();
                        appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(), appFundV2Info.getUserId(), giveReward, TokenTransactionTypeEnum.FUND_GIVE.getValue(), "");
                        break;
                    }
                }
            }catch (Exception e){
                log.info("incomeGive执行失败"+JSONObject.toJSONString(appFundV2Info)+"  错误信息"+e.getMessage());
            }
        }
    }


    public void weighting( BigDecimal message) {
        log.info("进入加权奖励:"+message);
        BigDecimal amount = message;
        Integer sss=1;
        try {
            List<AdminFundLevelConfig> ambassadors = adminFundLevelConfigMapper.getWeightDate();
            List<QueueWeightingReq> updateList = new ArrayList<>();
            for (AdminFundLevelConfig ambassador:ambassadors) {
                List<QueueWeightingReq> list = appFundInfoMapper.getUserByLevel(ambassador.getLevel());
                if(list == null || list.size()==0)continue;
                BigDecimal money = amount.multiply(ambassador.getWeightRate()).divide(new BigDecimal(list.size()),10, RoundingMode.HALF_UP);

                for (QueueWeightingReq req:list) {
                    BigDecimal bigDecimal = appFundInfoMapper.sumAmount(req.getUserId(),3);
                    BigDecimal ss = ambassadors.stream().filter(s->s.getLevel().equals(req.getLevel())).collect(Collectors.toList()).get(0).getWeightAmount();
                    if(ObjectUtils.isEmpty(bigDecimal) || bigDecimal.compareTo(ss)<0)continue;
                    boolean found = false;
                    for (QueueWeightingReq reqs : updateList) {
                        if (req.getUserId().equals(reqs.getUserId())) {
                            reqs.setAmount(reqs.getAmount().add(money));
                            found = true;
                            break;
                        }
                    }

                    if (!found) {
                        QueueWeightingReq queueWeightingReq = new QueueWeightingReq();
                        queueWeightingReq.setUserId(req.getUserId());
                        queueWeightingReq.setAmount(money);
                        updateList.add(queueWeightingReq);
                    }

                }
            }

            for (QueueWeightingReq req:updateList) {
                sss = req.getUserId();
                log.info("用户发放加权奖励:"+req.getUserId());
                if (!calculateConsumerValue.hasKey(calculateConsumerValue.getKey(), String.valueOf(req.getUserId())) && !calculateConsumerValue.isNewUser(req.getUserId())){
                    log.info("基金加权分红：用户{}不满足消费值条件",req.getUserId());
                    continue;
                }

                AppFundV2Info appFundV2Info = appFundV2InfoMapper.selectBYUserId(req.getUserId());
                if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(BigDecimal.ZERO) == 0)continue;

                if(ObjectUtils.isEmpty(appFundV2Info) || appFundV2Info.getRetained().compareTo(req.getAmount()) < 0){
                    log.info("服务奖：用户{}不满足服务奖留存金额", req.getUserId());
                    continue;
                }
                BigDecimal reward = req.getAmount();
                if(reward.compareTo(appFundV2Info.getRetained()) > 0){
                    reward = appFundV2Info.getRetained();
                }


                AppFundV2Info appFundV2Info1 = appFundInfoService.updateInfo(appFundV2Info.getUserId(),reward,BigDecimal.ZERO);

                AppFundV2Detail appFundV2Detail = new AppFundV2Detail();
                appFundV2Detail.setAmount(reward);
                appFundV2Detail.setUserId(req.getUserId());
                appFundV2Detail.setCreateTime(LocalDateTime.now());
                appFundV2Detail.setAfterAmount(appFundV2Info1.getRetained());
                appFundV2Detail.setType(4);
                appFundV2Detail.insert();
                appUserWalletService.updateWallet(LetokenTokenTypeEnum.LET.getId(),req.getUserId(),reward,TokenTransactionTypeEnum.FUND_WEIGHTING.getValue(),"");

                fundRelease(appFundV2Info.getUserId(),reward);


                log.info("结束发放加权奖励:"+req.getUserId());
            }
        } catch (Exception ex) {
            log.info("MQ >> 加权奖励执行失败:"+ex+"  失败用户id:"+sss);
        }
        log.info("加权奖励执行完成");
    }
}
